package com.tbit.uqbike.object.pojo.vo;

import cn.hutool.core.util.StrUtil;
import com.tbit.uqbike.annos.Excel;
import com.tbit.uqbike.constant.FaultType;
import com.tbit.uqbike.constant.MachineStateParseConstant;
import com.tbit.uqbike.webmanager.config.ManagerConfig;
import lombok.Data;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 运营地图车辆数据
 *
 * @Author:BUGTian
 * @DATE: 2022/11/7
 */
@Data
public class OperatingMapMachineStatus {
    private static final String SPLIT = ",";
    /**
     * 车辆id
     */
    private Integer machineId;
    /**
     * 分区编号
     */
    private Integer regionId;
    /**
     * 前分区编号
     */
    private Integer beforeRegionId;
    /**
     * 分区名称
     */
    @Excel(name = "分区", sort = 1)
    private String regionName;
    /**
     * 区域名称
     */
    private String accountName;
    /**
     * 设备编号
     */
    @Excel(name = "设备编号", sort = 3)
    private String machineNO;
    /**
     * 车辆编号
     */
    @Excel(name = "车辆编号", sort = 2)
    private String userCode;
    /**
     * 车辆类型  0:电单车  1：自行车
     */
    @Excel(name = "车辆类型", readConverterExp = "0=电单车,1=自行车", sort = 4)
    private Integer machineType;
    /**
     * 车架号
     */
    @Excel(name = "车架号", sort = 5)
    private String frame;
    /**
     * 车牌号
     */
    @Excel(name = "车牌号", sort = 6)
    private String license;
    /**
     * 电机号
     */
    @Excel(name = "电机号", sort = 7)
    private String motor;
    /**
     * 原始经度
     */
    private Double lon;
    /**
     * 原始纬度
     */
    private Double lat;
    /**
     * 校准经度
     */
    private Double lonC;
    /**
     * 校准纬度
     */
    private Double latC;
    /**
     * 定位时间
     */
    @Excel(name = "最后定位时间", dateFormat = "yyyy-MM-dd HH:mm:ss", sort = 10)
    private Date posDt;
    /**
     * 获取定位的方式，如 0-GPS定位(默认)  1-手动定位
     */
    private Integer posType;
    /**
     * 信号时间
     */
    private Date batDt;
    /**
     * 最后借出时间
     */
    @Excel(name = "最后借出时间", dateFormat = "yyyy-MM-dd HH:mm:ss", sort = 11)
    private Date lastBorrowTime;
    /**
     * 续航里程
     */
    private Integer surplusMileage;
    /**
     * 电量
     */
    @Excel(name = "电池电量", sort = 13)
    private Integer socPercent;


    //=====================车辆状态=======================//
    /**
     * 所属站点
     */
    @Excel(name = "所属站点", sort = 12)
    private String siteName;
    /**
     * 可运营
     */
    private boolean operational;

    //====================可运营========================//
    /**
     * 投放
     */
    private boolean putIn;
    /**
     * 骑行中
     */
    private boolean riding;
    /**
     * 闲置车辆-车辆已投放+12个小时未借出的车辆
     */
    private boolean unUsed;
    /**
     * 闲置时长
     */
    private Integer unUsedTimeHours;
    /**
     * 长时未定位车辆
     */
    private boolean longTermNonPos;
    /**
     * 长时未定位车辆时长
     */
    private Integer longTermNonPosHours;
    /**
     * 长时订单
     */
    private boolean longOrder;
    /**
     * 长时未定位车辆时长
     */
    private Integer longOrderTime;

    /**
     * 长时无订单时长
     */
    private Integer lastReturnTime;
    /**
     * 无盈利车辆-车辆已投放+12个小时未借出的车辆
     */
    private boolean noProfit;
    /**
     * 无盈利单数
     */
    private Integer noProfitCount;

    /**
     * 无订单
     */
    private Integer noOrder;
    /**
     * 正常
     */
    private boolean normal;
    /**
     * 站外
     */
    private boolean outSite;
    /**
     * 禁停区停车
     */
    private boolean noParkArea;
    /**
     * 电池未上锁
     */
    private boolean batteryUnLock;
    /**
     * 车辆休眠
     */
    private boolean machineSleep;
    /**
     * 电池电压
     */

    private Integer batteryEu;

    @Excel(name = "电池电压（V）", sort = 14)
    private Double batteryEuV;
    /**
     * 用户上报故障
     */
    private boolean userReportFault;
    /**
     * 运维上报故障
     */
    private boolean devOpsReportFault;
    /**
     * 头盔丢失可运营
     */
    private boolean helmetLoseCanOperational;

    //====================不可运营========================//
    /**
     * 头盔丢失不可运营
     */
    private boolean helmetLoseUnOperational;
    /**
     * 未关锁异常
     */
    private boolean machineUnLock;
    /**
     * 摄像头异常
     */
    private boolean cameraAbnormal;
    /**
     * 无信号
     */
    private boolean noSignal;
    /**
     * 超出区域
     */
    private boolean outArea;
    /**
     * 电池异常
     */
    private boolean batteryAbnormal;
    /**
     * 故障
     */
    private boolean fault;
    /**
     * 故障编号
     */
    private String faultCode;
    /**
     * 占用
     */
    private boolean isUse;
    /**
     * 缺电
     */
    private boolean powerShortage;
    /**
     * 馈电 soc = -1
     */
    private boolean powerFeed;
    /**
     * 丢失
     */
    private boolean lose;
    /**
     * 头盔丢失异常
     */
    private boolean helmetLose;
    /**
     * 头盔异常
     */
    private boolean helmetAbnormal;
    /**
     * 太阳能充电板异常
     */
    private boolean solarPanelAbnormal;
    /**
     * 用户上报故障不可运营
     */
    private boolean userReportFaultUnOperational;
    /**
     * 扣押车辆
     */
    private boolean detentionCar;
    /**
     * 库存车辆
     */
    private boolean stockCar;
    /**
     * 线上状态
     */
    @Excel(name = "在线状态", readConverterExp = "false=离线,true=在线", sort = 9)
    private boolean online;
    /**
     * 垂直停车
     */
    private boolean verticalPark;
    /**
     * 停车头盔丢失
     */
    private boolean parkHelmetLose;
    /**
     * 疑似故障
     * */
    private boolean suspectedFault;
    /**
     * 车辆状态解析
     */
    @Excel(name = "车辆状态", sort = 8)
    private String stateParse;
    //仓库名称
    private String warehouseName;
    //仓库id
    private Integer warehouseId;
    //扣押区名称
    private String detentionName;
    //扣押区id
    private Integer detentionId;
    //品牌
    private Integer brandId;
    //区域
    private Integer accountId;
    //电池编号
    private String batteryNO;

    @Excel(name = "车辆标签", sort = 15)
    private String tagList;
    private String tagIdList;


    /**
     * 判断线上状态
     */
    public void judgeOnline() {
        online = getOnline();
    }

    /**
     * 车辆状态解析
     */
    public String parseState() {
        List<String> states = new ArrayList<>();
        if (!putIn) {
            states.add(MachineStateParseConstant.UN_PUTIN);
            return stateParse = String.join(SPLIT, states);
        }
        if (Boolean.FALSE.equals(this.online)) {
            operational = false;
        }
        if (operational) {
            //正常运营
            states.add(MachineStateParseConstant.OPERATIONAL);
            if (riding) {
                states.add(MachineStateParseConstant.RIDING);
            } else {
                states.add(MachineStateParseConstant.FOR_RENT);
            }
        } else {
            //不可运营
            states.add(MachineStateParseConstant.UN_OPERATIONAL);
            if (noSignal || outArea || batteryAbnormal || helmetLoseUnOperational || userReportFaultUnOperational || Boolean.FALSE.equals(this.online)) {
                states.add(MachineStateParseConstant.ABNORMAL);
                if (noSignal) {
                    states.add(MachineStateParseConstant.NO_SIGNAL);
                }
                if (outArea) {
                    states.add(MachineStateParseConstant.OUT_AREA);
                }
                if (batteryAbnormal) {
                    states.add(MachineStateParseConstant.BATTERY_ABNORMAL);
                }
                if (userReportFaultUnOperational) {
                    states.add(MachineStateParseConstant.USER_REPORT_FAULT);
                }
                if (Boolean.FALSE.equals(this.online)) {
                    states.add(MachineStateParseConstant.OFFLINE);
                }
            }

            if (fault) {
                states.add(MachineStateParseConstant.FAULT);
                if (StrUtil.isNotBlank(faultCode)) {
                    states.add(FaultType.parseFaultsExceptUser(faultCode));
                }
            }
            if (isUse) {
                states.add(MachineStateParseConstant.IS_USE);
            }
            if (powerShortage) {
                states.add(MachineStateParseConstant.POWER_SHORTAGE);
            }
            if (powerFeed) {
                states.add(MachineStateParseConstant.POWER_FEED);
            }
            if (lose) {
                states.add(MachineStateParseConstant.LOSE);
            }
            if (helmetLose) {
                states.add(MachineStateParseConstant.HELMET_LOSE);
            }
        }
        if (suspectedFault) {
            states.add(MachineStateParseConstant.SUSPECTED_FAULT);
        }
        return stateParse = String.join(SPLIT, states);
    }

    /**
     * 获取线上状态
     *
     * @return
     */
    public boolean getOnline() {
        if (batDt == null) {
            return false;
        } else {
            int terOfflineSec = this.machineType == 0 ? ManagerConfig.TerOfflineSec : ManagerConfig.BIKE_TER_OFFLINE_SEC;
            return (System.currentTimeMillis() - batDt.getTime()) < terOfflineSec * 1000L;
        }
    }


}
